home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_100 / 168_01 / scn.c < prev    next >
Text File  |  1985-08-19  |  15KB  |  637 lines

  1. /* SDB - token scanning routines */
  2.  
  3. #include "stdio.h"
  4. #include "sdbio.h"
  5.  
  6. int dbv_token;                          /* current token */
  7. int dbv_tvalue;                         /* integer token value */
  8. char dbv_tstring[STRINGMAX+1];          /* string token value */
  9. struct ifile *dbv_ifp;                  /* indirect file context */
  10. struct macro *dbv_macros;               /* macro definitions */
  11. int dbv_fold;                           /* case fold alpha comparisons */
  12.  
  13. static char *iprompt,*cprompt;          /* input prompts */
  14. static char cmdline[LINEMAX+2],*lptr;   /* current line and pointer */
  15. static int atbol;                       /* flag indicating at bol */
  16. static int savech;                      /* lookahead character */
  17. static int savetkn;                     /* lookahead token */
  18. static char *keywords[] = {             /* keyword table */
  19.     "ascending",
  20.     "by",
  21.     "char",
  22.     "compress",
  23.     "create",
  24.     "define",
  25.     "delete",
  26.     "descending",
  27.     "exit",
  28.     "export",
  29.     "extract",
  30.     "from",
  31.     "help",
  32.     "insert",
  33.     "import",
  34.     "into",
  35.     "num",
  36.     "print",
  37.     "select",
  38.     "set",
  39.     "show",
  40.     "sort",
  41.     "update",
  42.     "using",
  43.     "where",
  44.     NULL
  45. };
  46. static int keytokens[] = {              /* token values for each keyword */
  47.     ASCENDING,
  48.     BY,
  49.     CHAR,
  50.     COMPRESS,
  51.     CREATE,
  52.     DEFINE,
  53.     DELETE,
  54.     DESCENDING,
  55.     EXIT,
  56.     EXPORT,
  57.     EXTRACT,
  58.     FROM,
  59.     HELP,
  60.     INSERT,
  61.     IMPORT,
  62.     INTO,
  63.     NUM,
  64.     PRINT,
  65.     SELECT,
  66.     SET,
  67.     SHOW,
  68.     SORT,
  69.     UPDATE,
  70.     USING,
  71.     WHERE,
  72.     NULL
  73. };
  74.  
  75. /* db_sinit - initialize the scanner */
  76. db_sinit()
  77. {
  78.     /* at beginning of line */
  79.     atbol = TRUE;
  80.  
  81.     /* make the command line null */
  82.     lptr = NULL;
  83.  
  84.     /* no lookahead yet */
  85.     savech = EOS;
  86.     savetkn = NULL;
  87.  
  88.     /* no indirect command files */
  89.     dbv_ifp = NULL;
  90.  
  91.     /* no macros defined */
  92.     dbv_macros = NULL;
  93.  
  94.     /* fold alpha comparisons */
  95.     dbv_fold = TRUE;
  96. }
  97.  
  98. /* db_prompt(ip,cp) - initialize prompt strings */
  99. db_prompt(ip,cp)
  100.   char *ip,*cp;
  101. {
  102.     /* save initial and continuation prompt strings */
  103.     iprompt = ip;
  104.     cprompt = cp;
  105. }
  106.  
  107. /* db_scan(fmt,args) - initiate line scan command parsing */
  108. db_scan(fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
  109. {
  110.     /* convert the command line and arguments */
  111.     sprintf(cmdline,fmt,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10);
  112.  
  113.     /* start at the beginning of the command line */
  114.     lptr = cmdline;
  115.     iprompt = NULL;
  116.     dbv_ifp = NULL;
  117.  
  118.     /* no lookahead yet */
  119.     savech = EOS;
  120.     savetkn = NULL;
  121.  
  122.     /* fold alpha comparisons */
  123.     dbv_fold = TRUE;
  124. }
  125.  
  126. /* db_flush - flush the current input line */
  127. int db_flush()
  128. {
  129.     while (savech != '\n')
  130.         if (savech > ' ')
  131.             return (db_ferror(SYNTAX));
  132.         else
  133.             savech = getchx();
  134.  
  135.     savech = EOS;
  136.     atbol = TRUE;
  137.     return (TRUE);
  138. }
  139.  
  140. /* db_gline - get a line from the current input */
  141. char *db_gline(buf)
  142.   char *buf;
  143. {
  144.     int ch,i;
  145.  
  146.     for (i = 0; (ch = getch()) != '\n' && ch != -1; )
  147.         if (i < LINEMAX)
  148.             buf[i++] = ch;
  149.         else {
  150.             printf("*** line too long ***\nRetype> ");
  151.             i = 0;
  152.         }
  153.     buf[i] = EOS;
  154.  
  155.     return (buf);
  156. }
  157.  
  158. /* db_ifile - setup an indirect command file */
  159. int db_ifile(fname)
  160.   char *fname;
  161. {
  162.     struct ifile *new_ifp;
  163.  
  164.     if ((new_ifp = malloc(sizeof(struct ifile))) == NULL)
  165.         return (db_ferror(INSMEM));
  166.     else if ((new_ifp->if_fp = fopen(fname,"r")) == NULL) {
  167.         free(new_ifp);
  168.         return (db_ferror(INDFNF));
  169.     }
  170.     new_ifp->if_mtext = NULL;
  171.     new_ifp->if_savech = savech;
  172.     new_ifp->if_lptr = lptr;
  173.     new_ifp->if_next = dbv_ifp;
  174.     dbv_ifp = new_ifp;
  175.  
  176.     /* return successfully */
  177.     return (TRUE);
  178. }
  179.  
  180. /* db_kill - kill indirect command file input */
  181. db_kill()
  182. {
  183.     struct ifile *old_ifp;
  184.  
  185.     while ((old_ifp = dbv_ifp) != NULL) {
  186.         dbv_ifp = old_ifp->if_next;
  187.         if (old_ifp->if_fp != NULL)
  188.             fclose(old_ifp->if_fp);
  189.         savech = old_ifp->if_savech;
  190.         lptr = old_ifp->if_lptr;
  191.         free(old_ifp);
  192.     }
  193.  
  194.     while (savech != '\n')
  195.         savech = getchx();
  196.  
  197.     savech = EOS;
  198.     savetkn = NULL;
  199.     atbol = TRUE;
  200. }
  201.  
  202. /* db_token - return the current input token */
  203. int db_token()
  204. {
  205.     struct macro *mptr;
  206.     struct ifile *new_ifp;
  207.  
  208.     /* find a token that's not a macro call */
  209.     while (db_xtoken() == ID) {
  210.  
  211.         /* check for a macro call */
  212.         for (mptr = dbv_macros; mptr != NULL; mptr = mptr->mc_next)
  213.             if (db_scmp(dbv_tstring,mptr->mc_name) == 0) {
  214.                 if ((new_ifp = malloc(sizeof(struct ifile))) == NULL)
  215.                     printf("*** error expanding macro: %s ***\n",dbv_tstring);
  216.                 else {
  217.                     new_ifp->if_fp = NULL;
  218.                     new_ifp->if_mtext = mptr->mc_mtext->mt_next;
  219.                     new_ifp->if_lptr = lptr; lptr = mptr->mc_mtext->mt_text;
  220.                     new_ifp->if_savech = savech; savech = EOS;
  221.                     new_ifp->if_next = dbv_ifp;
  222.                     dbv_ifp = new_ifp;
  223.                 }
  224.                 savetkn = NULL;
  225.                 break;
  226.             }
  227.  
  228.         if (mptr == NULL)
  229.             break;
  230.     }
  231.  
  232.     return (dbv_token);
  233. }
  234.  
  235. /* db_xtoken - return the current input token */
  236. int db_xtoken()
  237. {
  238.     int ch;
  239.  
  240.     /* check for a saved token */
  241.     if ((dbv_token = savetkn) != NULL)
  242.         return (dbv_token);
  243.  
  244.     /* get the next non-blank character */
  245.     ch = nextch();
  246.  
  247.     /* check type of character */
  248.     if (isalpha(ch))                    /* identifier or keyword */
  249.         get_id();
  250.     else if (isdigit(ch))               /* number */
  251.         get_number();
  252.     else if (ch == '"')                 /* string */
  253.         get_string();
  254.     else if (get_rel())                 /* relational operator */
  255.         ;
  256.     else                                /* single character token */
  257.         dbv_token = getch();
  258.  
  259.     /* save the lookahead token */
  260.     savetkn = dbv_token;
  261.  
  262.     /* return the token */
  263.     return (dbv_token);
  264. }
  265.  
  266. /* db_ntoken - get next token (after skipping the current one) */
  267. int db_ntoken()
  268. {
  269.     /* get the current token */
  270.     db_token();
  271.  
  272.     /* make sure another is read on next call */
  273.     savetkn = NULL;
  274.  
  275.     /* return the current token */
  276.     return (dbv_token);
  277. }
  278.  
  279. /* db_xntoken - get next token (after skipping the current one) */
  280. int db_xntoken()
  281. {
  282.     /* get the current token */
  283.     db_xtoken();
  284.  
  285.     /* make sure another is read on next call */
  286.     savetkn = NULL;
  287.  
  288.     /* return the current token */
  289.     return (dbv_token);
  290. }
  291.  
  292. /* db_scmp - compare two strings */
  293. int db_scmp(str1,str2)
  294.   char *str1,*str2;
  295. {
  296.     if (dbv_fold)
  297.         return (scmp(str1,str2));
  298.     else
  299.         return (strcmp(str1,str2));
  300. }
  301.  
  302. /* db_sncmp - compare two strings with a maximum length */
  303. int db_sncmp(str1,str2,len)
  304.   char *str1,*str2; int len;
  305. {
  306.     if (dbv_fold)
  307.         return (sncmp(str1,str2,len));
  308.     else
  309.         return (strncmp(str1,str2,len));
  310. }
  311.  
  312. /* scmp - compare two strings with alpha case folding */
  313. static int scmp(str1,str2)
  314.   char *str1,*str2;
  315. {
  316.     int ch1,ch2;
  317.  
  318.     /* compare each character */
  319.     while (*str1 && *str2) {
  320.  
  321.         /* fold the character from the first string */
  322.         if (isupper(*str1))
  323.             ch1 = tolower(*str1++);
  324.         else
  325.             ch1 = *str1++;
  326.  
  327.         /* fold the character from the second string */
  328.         if (isupper(*str2))
  329.             ch2 = tolower(*str2++);
  330.         else
  331.             ch2 = *str2++;
  332.  
  333.         /* compare the characters */
  334.         if (ch1 != ch2)
  335.             if (ch1 < ch2)
  336.                 return (-1);
  337.             else
  338.                 return (1);
  339.     }
  340.  
  341.     /* check for strings of different lengths */
  342.     if (*str1 == *str2)
  343.         return (0);
  344.     else if (*str1 == 0)
  345.         return (-1);
  346.     else
  347.         return (1);
  348. }
  349.  
  350. /* sncmp - compare two